package cn.restcloud.example.controller.mongo;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.Filters;

import cn.restcloud.example.dao.IDemoUserDao;
import cn.restcloud.example.model.UserModel;
import cn.restcloud.framework.core.annotation.bean.BeanConfig;
import cn.restcloud.framework.core.annotation.bean.BeanType;
import cn.restcloud.framework.core.annotation.bean.IocBeanId;
import cn.restcloud.framework.core.annotation.rest.MethodType;
import cn.restcloud.framework.core.annotation.rest.Param;
import cn.restcloud.framework.core.annotation.rest.Params;
import cn.restcloud.framework.core.annotation.rest.RestConfig;
import cn.restcloud.framework.core.base.IBasePageBean;
import cn.restcloud.framework.core.container.BeanFactory;
import cn.restcloud.framework.core.context.AppContext;
import cn.restcloud.framework.core.util.RequestUtil;
import cn.restcloud.framework.core.util.db.mongo.MongoUtil;
import cn.restcloud.framework.view.base.DocAndView;
import cn.restcloud.framework.view.util.ViewUtil;

/**
 * 关系数据库分页示例Demo
 * @author Administrator
 *
 */
@BeanConfig(appId = "example",beanId = "ListByPageMongoDemo",beanName = "Mongo数据库分页查询示例",beanType = BeanType.CONTROLLER,autowired = true,singleton = true,hotMode = true)
@RestConfig(url = "/rest/example/mongo/pages")
public class ListByPageMongoDemo {
	@IocBeanId(beanId = "DemoUserMongo") //指定注入MongoDB数据库的实现类
	private IDemoUserDao dao;
	
	/**
	 * Dao实现类中使用MongoPageUtil进行分页查询，只能通过filters,searchFilters传入查询条件有一定的灵活性限制
	 * 不能自定义写sql条件来选择数据，适合于查询全部数据并进行分页
	 * @return
	 */
	@RestConfig(configName = "分页查询用户数据",method = MethodType.GET,url = "/list1")
	@Params({
		@Param(id = "PageNo", name = "当前页兼容page"),
		@Param(id = "pageSize", name = "每页显示数兼容rows"),
		@Param(id = "sort", name = "动态排序字段"),
		@Param(id = "order", name = "排序方向ASC|DESC"),
		@Param(id = "filters", name = "动态过滤条件",sampleValue="{\"fieldName\":\"value\"}"),
		@Param(id = "searchFilters", name = "动态搜索条件",sampleValue="{\"title\":\"test\",\"content\":\"test\"}"),
	})
	public DocAndView listByPage_1() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPage();
		return ViewUtil.getJsonView(pageBean);
	}
	
	
	/**
	 * Dao实现类中使用继承的MongoBaseDao中的listByPage（）方法进行分页查询，可以自定义查询sql条件
	 * 不能动态传入filters,searchFilters条件进去，因为在Dao实现类中已经把sql条件固定死了
	 * 条件可以自已接收state参数然后传入
	 * @return
	 */
	@RestConfig(configName = "分页查询state=1的用户数据",method = MethodType.GET,url = "/list2")
	@Params({
		@Param(id = "PageNo", name = "当前页兼容page"),
		@Param(id = "pageSize", name = "每页显示数兼容rows"),
		@Param(id = "sort", name = "动态排序字段"),
		@Param(id = "order", name = "排序方向ASC|DESC")
	})
	public DocAndView listByPage_2() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPageAndState("1");
		return ViewUtil.getJsonView(pageBean);
	}
	
	/**
	 * Dao实现类中使用继承的MongoBaseDao中的listByPage（）方法进行分页查询，可以自定义查询条件
	 * 可以动态传入filters,searchFilters条件进去，因为在Dao实现类中可以合并filters条件和searchFilters条件
	 * @return
	 */
	@RestConfig(configName = "分页查询state=1的用户数据",method = MethodType.GET,url = "/list3")
	@Params({
		@Param(id = "PageNo", name = "当前页兼容page"),
		@Param(id = "pageSize", name = "每页显示数兼容rows"),
		@Param(id = "sort", name = "动态排序字段"),
		@Param(id = "order", name = "排序方向ASC|DESC"),
		@Param(id = "filters", name = "动态过滤条件",sampleValue="{\"fieldName\":\"value\"}"),
		@Param(id = "searchFilters", name = "动态搜索条件",sampleValue="{\"title\":\"test\",\"content\":\"test\"}")
	})
	public DocAndView listByPage_3() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPageAndState("1");
		return ViewUtil.getJsonView(pageBean);
	}
	
	/**
	 * Dao实现类中使用RdbUtil.listBeansByPage()方法进行分页查询
	 * @return
	 */
	@RestConfig(configName = "分页查询state=1的用户数据",method = MethodType.GET,url = "/list4")
	@Params({
		@Param(id = "PageNo", name = "当前页"),
		@Param(id = "pageSize", name = "每页显示数")
	})
	public DocAndView listByPage_4() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPageBySqlWhere("1");
		return ViewUtil.getJsonView(pageBean);
	}
	
	/**
	 * 直接组合一个自定义的filters去数据库中查询数据并分页
	 * 本方法虽然灵活快速（因为没有编写dao接口和实现类）但在架构分层上不太好，如果是为了快速实现功能可以用用，如果是构建一个好的产品最好是把数据的访问和sql的执行放到dao实现类中去
	 * @return
	 */
	@RestConfig(configName = "分页查询用户state=1的用户数据",method = MethodType.GET,url = "/list5")
	@Params({
		@Param(id = "PageNo", name = "当前页")
	})
	public DocAndView listByPage_5() throws Exception{
		//先生成一个pageBean对像用来返回查询后的数据
		@SuppressWarnings("unchecked")
		IBasePageBean<UserModel> pageBean=(IBasePageBean<UserModel>)BeanFactory.getBean("PageBean");
		String state="1"; //这里也可以使用RequestUtil.getString("state")来传入参数
		String dbName=AppContext.getSystemMongoDbName();
		String tableName="P_OrgPersons";
		String urlPageNo=RequestUtil.getString("pageNo");
		if(StringUtils.isBlank(urlPageNo)){urlPageNo="1";}
    	int pageNo=Integer.parseInt(urlPageNo);
		int pageSize=20;
		
		//查询条件
		Bson filters=Filters.eq("state",state);
		
		//先算出总文档数
    	long totalRecords=MongoUtil.getCount(dbName, tableName, filters);
    	
    	//再按条件进行分页查询
    	List<Document> list=new ArrayList<Document>();
    	FindIterable<Document> allDocs=MongoUtil.getCollection(dbName, tableName).find(filters); //按条件查询
    	Bson sortBson=new BasicDBObject("editTime", 1); //排序条件
    	MongoCursor<Document> cursor=allDocs.sort(sortBson).skip((pageNo - 1) * pageSize).limit(pageSize).iterator();
		while (cursor.hasNext()) {
            Document doc = cursor.next();
            list.add(doc);
		}
    	
		pageBean.setTotal((int)totalRecords);
    	pageBean.setPageDocs(list); //返回数据到pageBean中去
    	pageBean.setPageBeans(null);//pageBeans数据设置为null
    	
    	
		return ViewUtil.getJsonView(pageBean);
	}
	
}
